package dao

import (
	"bytes"
	"context"
	"encoding/json"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"net/http"
	"smart-health-platforms/config"
	inits "user_srv/internal/mq"
	"user_srv/user"

	"smart-health-platforms/pkg"
	"user_srv/model"
)

type ChatDao struct {
	db *gorm.DB
}

// NewChatDao 创建一个新的 ChatDao 实例

func NewChatDao(db *gorm.DB) *ChatDao {
	return &ChatDao{
		db: db,
	}
}

func (d *ChatDao) callTongYi(ctx context.Context, model, content, key, url string) (string, error) {
	// 1. 构造请求体
	body, _ := json.Marshal(map[string]any{
		"model": model,
		"input": map[string]any{
			"messages": []map[string]any{{"role": "user", "content": content}},
		},
		"parameters": map[string]any{"stream": false},
	})
	// 2. 构造http请求
	req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+key)

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	var r struct{ Output struct{ Text string } }
	if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
		return "", err
	}
	return r.Output.Text, nil
}

// CreateChat 把ai的聊天记录保存到数据库
func (d *ChatDao) AskAndSave(ctx context.Context, userId int64, content, modelStr, apiKey, apiUrl string) (string, error) {
	// 1. 构造请求体
	reply, err := d.callTongYi(ctx, modelStr, content, apiKey, apiUrl)
	if err != nil {
		return "", err
	}

	log := &model.ChatLogs{
		UserId:  uint(userId),
		Model:   modelStr,
		Message: string(must(json.Marshal(map[string]string{"content": content}))),
		Reply:   reply,
	}
	return reply, d.db.Create(log).Error
}

// 辅助：忽略错误的 marshal
func must(b []byte, _ error) []byte { return b }

func SendMessage(senderId, receiverId, msgType int64, content string) {
	// 创建消息对象
	message := &model.Message{
		SenderID:   senderId,
		ReceiverID: receiverId,
		Content:    content,
		Type:       int(msgType),
		IsRead:     0,
	}
	err2 := message.CreateMessage()
	if err2 != nil {
		pkg.Warn("消息入库失败")
		return
	}

	// 将消息发送到RabbitMQ队列，异步处理
	messageJSON, err := json.Marshal(message)
	if err != nil {
		pkg.Warn("消息序列化失败")
		return
	}

	// 创建RabbitMQ实例并发送消息
	rabbitmq := inits.NewRabbitMQSimple("user_message_queue")
	err = rabbitmq.PublishSimple(messageJSON)
	if err != nil {
		pkg.Warn("rabbitmq生产信息失败")
		return
	}
	return
}

// MarkMessageRead 标记消息已读
func MarkMessageRead(messageId int64, isRead int) error {
	var messageModel model.Message
	err := messageModel.MarkAsRead(messageId, isRead) // 标记消息已读
	if err != nil {
		pkg.Warn("标记消息已读失败", zap.Error(err))
		return err
	}
	return nil
}

// GetUnreadCount 获取未读消息数量
func GetUnreadCount(userId int64) int64 {
	var messageModel model.Message
	count, err := messageModel.GetUnreadCount(int64(userId))
	if err != nil {
		pkg.Warn("获取未读消息数量失败", zap.Error(err))
		return 0
	}
	return count
}

// MarkMessageRead 标记消息已读
func GetMessageList(userId, Page, PageSize int64) ([]*user.MessageInfo, int64, error) {
	var messageModel model.Message
	messages, err := messageModel.GetMessageList(userId, int(Page), int(PageSize))
	if err != nil {
		return nil, 0, err
	}

	// 转换为响应格式
	var messageList []*user.MessageInfo
	for _, msg := range messages {
		createdAt := msg.CreatedAt.Format("2006-01-02 15:04:05")
		var readTime string
		if msg.ReadTime != nil {
			readTime = msg.ReadTime.Format("2006-01-02 15:04:05")
		}

		messageList = append(messageList, &user.MessageInfo{
			Id:        int64(msg.ID),
			SenderId:  msg.SenderID,
			Content:   msg.Content,
			Type:      int32(msg.Type),
			IsRead:    int32(msg.IsRead),
			CreatedAt: createdAt,
			ReadTime:  readTime,
		})
	}

	// 获取总数
	var total int64
	config.DB.Model(&model.Message{}).Where("receiver_id = ?", userId).Count(&total)

	return messageList, total, nil
}
